package concurrent.c_012_ThreadPool;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;

/**
 * 线程池的概念
 */
public class T05_ThreadPool {

    static final ThreadPoolExecutor tpe = new ThreadPoolExecutor(10, 10, 60L,
            TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 15; i++) {
            tpe.execute(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                    // System.in.read();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            });
        }

        System.out.println(tpe.getQueue());
        tpe.execute(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(500);
                // System.in.read();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        });
        System.out.println(tpe.getQueue());

        System.out.println(tpe);

        tpe.shutdown();
        System.out.println(tpe.isTerminated());
        System.out.println(tpe.isShutdown());
        System.out.println(tpe);

        TimeUnit.SECONDS.sleep(5);
        System.out.println(tpe.isTerminated());
        System.out.println(tpe.isShutdown());
        System.out.println(tpe);

        // ThreadFactory 使用
        MyThreadFactory factory = new MyThreadFactory("MyThreadFactory");
        Thread thread = factory.newThread(() -> System.out.println(Thread.currentThread().getName()));
        thread.start();
    }

    /**
     * ThreadFactory 是一个线程工厂。用来创建线程。
     * 为了统一在创建线程时设置一些参数，如是否守护线程。线程一些特性等，如优先级。
     * 通过这个 TreadFactory 创建出来的线程能保证有相同的特性。它首先是一个接口类，而且方法只有一个。就是创建一个线程。
     */
    static class MyThreadFactory implements ThreadFactory {
        private int counter;
        private final String name;
        private final List<String> stats;

        public MyThreadFactory(String name) {
            counter = 0;
            this.name = name;
            stats = new ArrayList<>();
        }

        @Override
        public Thread newThread(Runnable run) {
            Thread t = new Thread(run, name + "-Thread-" + counter);
            counter++;
            stats.add(String.format("Created thread %d with name %s on%s\n", t.getId(), t.getName(), new Date()));
            return t;
        }

        public String getStas() {
            StringBuffer buffer = new StringBuffer();
            Iterator<String> it = stats.iterator();
            while (it.hasNext()) {
                buffer.append(it.next());
                buffer.append("\n");
            }
            return buffer.toString();
        }
    }
}
